﻿using DbSync;
using DBSync.Util;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

namespace DBSync.wpfPage
{
    /// <summary>
    /// Interaction logic for OrganizationPage.xaml
    /// </summary>
    public partial class OrganizationPage : Page
    {
        private static OrganizationPage instance;
        private syncdbEntities db;
        private int organizationId;
        private static bool organizationSelected = false;

        public OrganizationPage()
        {
            InitializeComponent();
        }

        public static OrganizationPage Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new OrganizationPage();
                }
                return instance;
            }
        }

        private void btnSettingsReset_Click(object sender, RoutedEventArgs e)
        {
            txtOrganizationName.Text = "";
            txtUsername.Text = "";
            txtPassword.Password = "";
            txtConfirmPassword.Password = "";
        }

        private void btnSettingsSave_Click(object sender, RoutedEventArgs e)
        {
            tbl_organization organization = null;
            db = new syncdbEntities();
            if (organizationExist(txtOrganizationName.Text))
            {
                ConfirmationWindow conf = new ConfirmationWindow("Add User", "Organization already exists. Are you sure to add user?");
                conf.ShowDialog();
                if (ConfirmationWindow.isConfirm == MessageBoxResult.No)
                {
                    return;
                }
                else
                {
                    organizationId = db.tbl_organization.Where(o => o.ORGANIZATION_NAME == txtOrganizationName.Text).Select(o => o.ID).First();
                }
            }
            else
            {
                if (txtOrganizationName.Text != null && txtOrganizationName.Text != "")
                {
                    organization = new tbl_organization();
                    organization.ORGANIZATION_NAME = txtOrganizationName.Text;
                    organization.INSERTDATE = DateTime.Now;
                    organization.UPDATEDATE = DateTime.Now;
                    organization.STATUS = 0;

                    db.tbl_organization.Add(organization);
                    int status = db.SaveChanges();
                    if (status > 0)
                    {
                        organizationId = organization.ID;
                        bool isPhrDbCreated = copyDatabaseSchema(SyncKeys.PHRDBNAME_DEFAULT, SyncKeys.PHRDBNAME_DEFAULT + "_" + organizationId);
                        bool isDcdrDbCreated = copyDatabaseSchema(SyncKeys.DCDRDBNAME_DEFAULT, SyncKeys.DCDRDBNAME_DEFAULT + "_" + organizationId);

                        if (!isPhrDbCreated || !isDcdrDbCreated)
                        {
                            MSGWindow msgw = new MSGWindow("Error", "Database cannot be created. Please contact administrator");
                            msgw.ShowDialog();
                            return;
                        }
                    }

                }
                else
                {
                    MSGWindow msgw = new MSGWindow("Error", "Organization name is required");
                    msgw.ShowDialog();
                }
            }
            if (organizationId > 1)
            {
                if (txtUsername.Text != "" && txtPassword.Password != "")
                {
                    if (txtPassword.Password == txtConfirmPassword.Password)
                    {
                        if (usernameExsist(txtUsername.Text))
                        {
                            MSGWindow msgw = new MSGWindow("Error", "Username is already exists. Please enter different username");
                            msgw.ShowDialog();
                            return;
                        }
                        else
                        {
                            tbl_user user = new tbl_user();
                            user.USERNAME = txtUsername.Text;
                            user.PASSWORD = txtPassword.Password;
                            user.ROLE = "user";
                            user.ORGANIZATION_ID = organizationId;
                            user.STATUS = 0;
                            user.INSERTDATE = DateTime.Now;
                            user.UPDATEDATE = DateTime.Now;

                            db.tbl_user.Add(user);
                            int status = db.SaveChanges();
                            if (status > 0)
                            {
                                MSGWindow msgw = new MSGWindow("Success", "Organization record added successfully");
                                msgw.ShowDialog();
                                instance = null;
                                MainWindow.Instance.ContentFrame.Content = ViewUser.Instance;

                            }
                        }
                    }
                    else
                    {
                        MSGWindow msgw = new MSGWindow("Error", "Password and confirmation not matched");
                        msgw.ShowDialog();
                    }
                }
                else
                {
                    MSGWindow msgw = new MSGWindow("Error", "Username and Password fields are required");
                    msgw.ShowDialog();
                }
            }
            else
            {
                MSGWindow msgw = new MSGWindow("Error", "Select or enter valid organization name");
                msgw.ShowDialog();
            }



        }

        private bool usernameExsist(string p)
        {
            try
            {
                tbl_user user = db.tbl_user.Where(u => u.USERNAME == txtUsername.Text).FirstOrDefault();
                if (user == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                MSGWindow msgw = new MSGWindow("Error", "Connection failure. Please try again");
                msgw.ShowDialog();
                return false;
            }
        }

        private bool organizationExist(string name)
        {
            try
            {
                tbl_organization organization = db.tbl_organization.Where(o => o.ORGANIZATION_NAME == txtOrganizationName.Text).FirstOrDefault();
                if (organization == null)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                MSGWindow msgw = new MSGWindow("Error", "Connection failure. Please try again");
                msgw.ShowDialog();
                return false;
            }
        }


        //private bool createDatabaseInServer(int orgId)
        //{
        //    try
        //    {
        //        System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        //        var settings = config.AppSettings.Settings;
        //        string server = settings[SyncKeys.HOST].Value;
        //        string port = settings[SyncKeys.PORT].Value;
        //        string username = settings[SyncKeys.USERNAME].Value;
        //        string password = settings[SyncKeys.PASSWORD].Value;

        //        SqlConnection conn = new SqlConnection("Server=" + server + "," + port + ";Integrated Security=False;User ID=" + username + ";Password=" + password + ";Application Name=30");
        //        String str = "USE master;  CREATE DATABASE " + SyncKeys.PHRDBNAME_DEFAULT + "_" + orgId +"; ";
        //        SqlCommand command = new SqlCommand(str, conn);
        //        conn.Open();
        //        command.ExecuteNonQuery();

        //        str = "USE master;  CREATE DATABASE " + SyncKeys.DCDRDBNAME_DEFAULT + "_" + orgId +"; ";
        //        command = new SqlCommand(str, conn);
        //        command.ExecuteNonQuery();

        //        conn.Close();

        //        return true;
        //    }
        //    catch(Exception ex)
        //    {
        //        MSGWindow msgw = new MSGWindow("Error", "Failed to create database. Check Internet connection");
        //        //MSGWindow msgw = new MSGWindow("Error", ex.Message);
        //        msgw.ShowDialog();
        //        return false;
        //    }
        //}

        private bool copyDatabaseSchema(string srcDbName, string tarDbName)
        {
            try
            {
                System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                var settings = config.AppSettings.Settings;
                string server = settings[SyncKeys.HOST].Value;
                string port = settings[SyncKeys.PORT].Value;
                string username = settings[SyncKeys.USERNAME].Value;
                string password = settings[SyncKeys.PASSWORD].Value;

                ServerConnection serverConnection = new ServerConnection(server + "\\SQLEXPRESS");
                serverConnection.LoginSecure = false;
                serverConnection.Login = username;
                serverConnection.Password = password;
                Server srv = new Server(serverConnection);

                Database sourceDB = srv.Databases[srcDbName];

                Database targetDB = new Database(srv, tarDbName);
                targetDB.Create();

                Transfer transfer = new Transfer(sourceDB);

                transfer.CopyAllObjects = true;
                //transfer.CopyAllUsers = true;
                transfer.Options.WithDependencies = true;
                transfer.Options.DriAllKeys = true;
                transfer.DestinationDatabase = targetDB.Name;
                transfer.DestinationServer = srv.Name;
                transfer.DestinationLoginSecure = false;
                transfer.DestinationLogin = settings[SyncKeys.USERNAME].Value;
                transfer.DestinationPassword = settings[SyncKeys.PASSWORD].Value;
                transfer.CopySchema = true;
                transfer.CopyData = true;
                transfer.Options.ContinueScriptingOnError = true;

                transfer.ScriptingProgress += new ProgressReportEventHandler(transfer_ScriptingProgress);
                transfer.DataTransferEvent += new DataTransferEventHandler(transfer_DataTransferEvent);

                transfer.ScriptTransfer();
                transfer.TransferData();
                return true;
            }
            catch (Exception ex)
            {
                MSGWindow msgw = new MSGWindow("Error", "Failed to create database. Check Internet connection");
                msgw.ShowDialog();
                return false;
            }

        }

        void transfer_DataTransferEvent(object sender, Microsoft.SqlServer.Management.Common.DataTransferEventArgs e)
        {
            Console.WriteLine(e.DataTransferEventType.ToString() + " : " + e.Message);
        }

        void transfer_ScriptingProgress(object sender, ProgressReportEventArgs e)
        {
            Console.Write("Progress {0} of {1} . . . {2} \n", e.TotalCount, e.Total, e.Current);
            //Application.Current.Dispatcher.Invoke((Action)(() =>
            //{
            lblStatus.Content = "dbname";
            float a = (e.TotalCount / e.Total) * 100;
            int b = (int)a;
            int percentageCompleted = (int)(((float)e.TotalCount / (float)e.Total) * 100);
            progDB.Value = percentageCompleted;
            lblPercent.Content = percentageCompleted + "%";
            if (percentageCompleted == 100)
            {
                lblStatus.Content = "Complete";
            }
            //else
            //{
            //    lblStatus.Content = "";
            //}
            //}));
        }



        private void Page_Loaded_1(object sender, RoutedEventArgs e)
        {
            MainWindow.Instance.btn_home.Visibility = System.Windows.Visibility.Hidden;
            MainWindow.Instance.btn_settings.Visibility = System.Windows.Visibility.Hidden;
            MainWindow.Instance.btn_add_organization.Visibility = System.Windows.Visibility.Hidden;
            MainWindow.Instance.btn_view_organization.Visibility = System.Windows.Visibility.Visible;
            MainWindow.Instance.btn_logout.Visibility = System.Windows.Visibility.Visible;
        }

        private void lst_organization_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            txtOrganizationName.Text = lst_organization.SelectedValue.ToString().Trim();
            lst_organization.Visibility = System.Windows.Visibility.Hidden;
            if (txtOrganizationName.Text != null && txtOrganizationName.Text != "")
            {
                organizationSelected = true;
            }
        }

        private void btn_view_organization_list_Click(object sender, RoutedEventArgs e)
        {
            if (lst_organization.Visibility == System.Windows.Visibility.Visible)
            {
                lst_organization.Visibility = System.Windows.Visibility.Hidden;
            }
            else
            {
                syncdbEntities db = new syncdbEntities();
                lst_organization.ItemsSource = db.tbl_organization.Where(o => o.STATUS == 0).Select(o => o.ORGANIZATION_NAME).ToList();
                lst_organization.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void lst_organization_MouseUp(object sender, MouseButtonEventArgs e)
        {
            lst_organization.Visibility = System.Windows.Visibility.Hidden;
        }

        private void txtOrganizationName_TextChanged(object sender, TextChangedEventArgs e)
        {
            lst_organization.Visibility = System.Windows.Visibility.Hidden;
        }
    }
}
